package com.atguigu.gmall.activity.controller;

import com.atguigu.gmall.activity.service.SeckillGoodsService;
import com.atguigu.gmall.activity.util.CacheHelper;
import com.atguigu.gmall.activity.util.DateUtil;
import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.common.result.ResultCodeEnum;
import com.atguigu.gmall.common.util.AuthContextHolder;
import com.atguigu.gmall.common.util.MD5;
import com.atguigu.gmall.model.activity.SeckillGoods;
import com.atguigu.gmall.model.activity.UserRecode;
import com.atguigu.gmall.mq.constants.MqConst;
import com.atguigu.gmall.mq.service.RabbitService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 秒杀管理
 */
@RestController
@RequestMapping("/api/activity/seckill")
public class SeckillApiController {

    @Autowired
    private SeckillGoodsService seckillGoodsService;
    @Autowired
    private RabbitService rabbitService;

    //开始秒杀
    @PostMapping("/auth/seckillOrder/{skuId}")
    public Result seckillOrder(@PathVariable(name = "skuId") String skuId,String skuIdStr,HttpServletRequest
                               request){
        String userId = AuthContextHolder.getUserId(request);
//        1、校验下单码
        if(StringUtils.isEmpty(skuIdStr)){
            //请求不合法
            return Result.build(null,ResultCodeEnum.SECKILL_ILLEGAL);
        }else if(MD5.encrypt(userId).equals(skuIdStr)){
            /// 2、校验当前商品状态位（0，1）
            String state = (String) CacheHelper.get(skuId);
            if(!StringUtils.isEmpty(state) && "1".equals(state)){
                //下单码正确 同时 有库存
                //发消息  用户ID 库存ID
                UserRecode userRecode = new UserRecode();
                //库存ID
                userRecode.setSkuId(Long.parseLong(skuId));
                //用户ID
                userRecode.setUserId(userId);
                //发消息 MQ
                rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_SECKILL_USER,
                        MqConst.ROUTING_SECKILL_USER,userRecode);
            }else{
                //已售完
                return Result.build(null,ResultCodeEnum.SECKILL_FINISH);
            }
        }else{
            //请求不合法
            return Result.build(null,ResultCodeEnum.SECKILL_ILLEGAL);
        }
        //开启轮循查询的开关
        return Result.ok();
    }



    //立即抢购  获取下单码
    @GetMapping("/auth/getSeckillSkuIdStr/{skuId}")
    public Result getSeckillSkuIdStr(@PathVariable(name = "skuId") String skuId, HttpServletRequest request) {
        String userId = AuthContextHolder.getUserId(request);
        //下单码
        String encrypt = null;
        //0:入参 skuId 查询秒杀商品
        SeckillGoods seckillGoods = seckillGoodsService.seckillDetail(skuId);
        //1:入参 skuId 此商品开始时间 结束时间  跟当前时间 比大小
        // //开始时间大于结束时间 是false
        // //开始时间小于等于 结束时间 是 true
        if (!DateUtil.dateCompare(seckillGoods.getStartTime(), new Date())) {
            //活动尚未开始
            return Result.build(null, ResultCodeEnum.SECKILL_NO_START);
        }
        if (!DateUtil.dateCompare(new Date(), seckillGoods.getEndTime())) {
            //活动结束了
            return Result.build(null, ResultCodeEnum.SECKILL_END);
        }
        if (DateUtil.dateCompare(seckillGoods.getStartTime(), new Date()) &&
                DateUtil.dateCompare(new Date(), seckillGoods.getEndTime())) {
            //活动开始了  活动正在进行中。。没有结束
            //2:入参 skuId 此商品剩余库存为0  此活动已结束
            if(seckillGoods.getStockCount().intValue() >= 0){
                //3:入参 skuId 此商品的状态 （未审核或是不通过的）
                if("1".equals(seckillGoods.getStatus())){
                    //4:生成下单码
                    // 1)UUID  保存缓存一份 下次请求校验
                    // 2)MD5.encrypt(userId)  字符串 下单码
                    encrypt = MD5.encrypt(userId);
                    // 3)MD5.encrypt(userId + skuId)  字符串 下单码
                }else{
                    //  请求不合法
                    return Result.build(null, ResultCodeEnum.SECKILL_ILLEGAL);
                }
            }else{
                //已售完
                return Result.build(null, ResultCodeEnum.SECKILL_FINISH);
            }
        }
        //成功获取下单码
        return Result.ok(encrypt);
    }


    //查询秒杀商品集合
    @GetMapping("/list")
    public List<SeckillGoods> list() {
        return seckillGoodsService.list();
    }

    //查询一个秒杀商品
    @GetMapping("/seckill/{skuId}")
    public SeckillGoods seckillDetail(@PathVariable(name = "skuId") String skuId) {
        return seckillGoodsService.seckillDetail(skuId);
    }


    @Autowired
    private RedisTemplate redisTemplate;

    //轮循查询抢购结果  /auth/checkOrder/' + skuId,   每3秒执行一次
    @GetMapping("/auth/checkOrder/{skuId}")
    public Result checkOrder(@PathVariable(name = "skuId") String skuId,HttpServletRequest request){
        String userId = AuthContextHolder.getUserId(request);
        //此用户确定过来抢购了    排队中。 无库存
        Object o = redisTemplate.opsForValue().get("user:" + userId + "skuId:" + skuId);
        if(null != o){
            /// 此用户已经来过  已经来抢购了
//        1、抢购成功（已下单）
            Object o1 = redisTemplate.opsForValue().get(RedisConst.SECKILL_ORDERS_USERS + userId);
            if(null != o1){
                return Result.build(null,ResultCodeEnum.SECKILL_ORDER_SUCCESS);
            }
//        2、抢购成功（资格）
            Object o2 = redisTemplate.opsForValue().get(RedisConst.SECKILL_ORDERS + userId);
            if(null != o2){
                return Result.build(null,ResultCodeEnum.SECKILL_SUCCESS);
            }
        //        3、抢购失败
            return Result.build(null,ResultCodeEnum.SECKILL_FAIL);
        }else{
//        4、排队中
            //用户没有来抢购商品  MQ队列排队着呢
            return Result.build(null,ResultCodeEnum.SECKILL_RUN);
        }
    }

}
